﻿using System;
using System.Collections.Generic;
using System.Threading; 
using System.Collections; 
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Security.Permissions;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
 
public delegate void BookmarkLocation(Bookmark resumed);

[Serializable]
public class Bookmark
{
    public Bookmark(string name, BookmarkLocation continueAt)
    {
        Name = name;
        ContinueAt = continueAt;
    }

    public string Name { get; set; }
    public BookmarkLocation ContinueAt { get; set; }
    public object Payload { get; set; }

    public BookmarkManager BookmarkManager { get; set; }
}

public class BookmarkManager
{
    private List<Bookmark> bookmarkList;

    private ProgramStatement currentProgramStatement;

    public BookmarkManager()
    {
        bookmarkList = new List<Bookmark>();
    }

    public void Add(Bookmark bookmark)
    {
        bookmarkList.Add(bookmark);
        bookmark.BookmarkManager = this;
    }

    public void Remove(Bookmark bookmark)
    {
        bookmarkList.Remove(bookmark);
    }

    public void Resume(string bookmarkName, object payload)
    {
        foreach (Bookmark bookmark in bookmarkList)
        {
            if (bookmark.Name == bookmarkName)
            {
                bookmark.Payload = payload;
                bookmark.ContinueAt(bookmark);

                break;
            }
        }
    }

    // Request execution of a program statement, using an
    // implicit bookmark that will be resumed when that
    // program statement completes its execution
    public void RunProgramStatement(ProgramStatement statement, BookmarkLocation continueAt)
    {
        currentProgramStatement = statement;
        Bookmark bookmark = new Bookmark(statement.GetType().FullName, continueAt);
        Add(bookmark);
        statement.Run(this);
    }

    // Indicate that the current program statement is done,
    // so that internally managed bookmarks can be resumed
    public void Done(bool bAllDone)
    {
        if (!bAllDone)
            Resume(currentProgramStatement.GetType().FullName, currentProgramStatement);
        else
            bookmarkList.Clear();
    }
}

[Serializable]
public abstract class ProgramStatement //: DependencyObject
{
    public abstract ActivityExecutionStatus Run(BookmarkManager mgr);
    private IDictionary<DependencyProperty, object> dependencyPropertyValues;
    private IDictionary<DependencyProperty, object> metaProperties = new Dictionary<DependencyProperty, object>(); //Binding
        
    private String name;
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
        }
    }
    internal IDictionary<DependencyProperty, object> DependencyPropertyValues
    {
        get
        {
            if (this.dependencyPropertyValues == null)
            {
                this.dependencyPropertyValues = new Dictionary<DependencyProperty, object>();
            }
            return this.dependencyPropertyValues;
        }
    }
    
    public object GetValue(DependencyProperty dependencyProperty)
    {        
        if (dependencyProperty == null)
        {
            throw new ArgumentNullException("dependencyProperty");
        }

        object result;
        if (!metaProperties.ContainsKey(dependencyProperty))
         {
              this.DependencyPropertyValues.TryGetValue( dependencyProperty , out result);
         }
         else
         {
              this.DependencyPropertyValues.TryGetValue((DependencyProperty)metaProperties[dependencyProperty], out result);        
         }
        if (result is ActivityBind)
        {
            object runtimeValue = null;
            Activity dataSourceObject = Helpers.ParseActivityForBind(activity, this.Name);
            if (dataSourceObject != null)
            {
                MemberInfo memberInfo = GetMemberInfo(dataSourceObject.GetType(), this.Path, targetType);
                if (memberInfo != null)
                {
                    runtimeValue = GetMemberValue(dataSourceObject, memberInfo, this.Path, targetType);
                    if ((runtimeValue is ActivityBind) && (BindHelpers.GetMemberType(memberInfo) != typeof(ActivityBind)))
                    {
                        runtimeValue = ((ActivityBind)runtimeValue).GetRuntimeValue(dataSourceObject, targetType);
                    }
                    return runtimeValue;
                }
                DependencyProperty.FromName(this.Path, Helpers.GetRootActivity(activity).GetType());
            }
            return runtimeValue;
        }
        return result;
    }

    public void SetValue(DependencyProperty dependencyProperty, object value)
    {
        if (dependencyProperty == null)
        {
            throw new ArgumentNullException("dependencyProperty");
        }
         this.DependencyPropertyValues[dependencyProperty] = value;
    }

    public void SetBinding(DependencyProperty dependencyProperty, ActivityBind bind)
    {
         if (this.metaProperties.ContainsKey(dependencyProperty))
         {
              this.metaProperties[dependencyProperty] = bind;
         }
         else
         {
              this.metaProperties.Add(dependencyProperty, bind);
         }
    }
}

[Serializable]
public class ProgramStatementBlock : ProgramStatement
{
    int currentIndex;
    List<ProgramStatement> statements = new List<ProgramStatement>();
    public IList<ProgramStatement> Statements
    {
        get { return statements; }
    }

    public override ActivityExecutionStatus Run(BookmarkManager mgr)
    {
        currentIndex = 0;

        // Empty statement block
        if (statements.Count == 0)
            mgr.Done(true);
        else
            mgr.RunProgramStatement(statements[0], ContinueAt);

        return ActivityExecutionStatus.Closed;
    }

    public void ContinueAt(Bookmark resumed)
    {
        BookmarkManager mgr = resumed.BookmarkManager;

        // If we've run all the statements, we're done
        if (++currentIndex == statements.Count)
            mgr.Done(true);
        else // Else, run the next statement
            mgr.RunProgramStatement(statements[currentIndex], ContinueAt);
    }


}

public class MythicalRuntime
{
    Dictionary<ProgramHandle, ProgramStatement> ht;

    private BookmarkManager mgr = new BookmarkManager();

    public MythicalRuntime()
    {
        ht = new Dictionary<ProgramHandle, ProgramStatement>();
    }

    public BookmarkManager Mgr
    {
        get { return mgr; }
        set { mgr = value; }
    }

    public ProgramHandle RunProgram(ProgramStatement program)
    {
        //这个新的Guid根据规则创建,而不是简单的new Guid(),以下仅为模拟方法
        Guid programId = new Guid();

        ProgramHandle programHandle = new ProgramHandle();
        programHandle.ProgramId = programId;

        ht.Add(programHandle, program);

        //Bookmark的上半部分，用新的thread执行
        ThreadPool.QueueUserWorkItem(state => program.Run(state as BookmarkManager), Mgr);

        return programHandle;
    }

    public ProgramHandle GetProgramHandle(Guid programId)
    {
        //根据programId恢复已经钝化的程序,假设恢复为read方法
        ProgramStatement program = null; // = new Read();

        //重新构建ProgramHandle
        ProgramHandle programHandle = new ProgramHandle();
        programHandle.ProgramId = programId;

        //重新加载到内存
        ht.Add(programHandle, program);

        return programHandle;
    }

    public void Shutdown()
    {
        //从内存中取出所有ProgramHandle, 依次钝化
        foreach (ProgramHandle tmpProgramHandle in ht.Keys)
        {
            ProgramStatement program = ht[tmpProgramHandle];
            tmpProgramHandle.Passivate(program);
        }

        ht = null;
    }
}

public class ProgramHandle
{
    private Guid programId;

    public Guid ProgramId
    {
        get { return programId; }
        set { programId = value; }
    }

    public void Passivate(ProgramStatement program)
    {
        //将program根据关键字programId进行钝化
    }

    public void Resume(string bookmarkName, object payload)
    {
        BookmarkManager mgr = new BookmarkManager();
        mgr.Resume(bookmarkName, payload);
    }
}

public enum ActivityExecutionStatus { Initialized=0, Executing=1, Canceling=2, Closed=3, Compensating=4,  Faulting=5   };

public class DependencyProperty
{
    private string name = string.Empty;
    private Type ownerType;
    private Type propertyType;
    private static IDictionary<int, DependencyProperty> dependencyProperties = new Dictionary<int, DependencyProperty>();
         
    private DependencyProperty(string name, Type propertyType, Type ownerType )
    {
        this.name = name;
        this.propertyType = propertyType;
        this.ownerType = ownerType;
    }
    public static DependencyProperty Register(string name, Type propertyType, Type ownerType)
    {
        DependencyProperty property = new DependencyProperty(name, propertyType, ownerType ); 
         dependencyProperties.Add(property.GetHashCode(), property);
         return property;
    } 
}

public sealed class ActivityBind //: MarkupExtension
{
    //public ActivityBind();
    //public ActivityBind(string name);
    //public ActivityBind(string name, string path);
    public string Name { get; set; }
    public string Path { get; set; }
    //public object GetRuntimeValue(ProgramStatement activity);
    //public void SetRuntimeValue(ProgramStatement activity, object value);
    /* *** other members *** */
}
    //[Serializable]
    //public sealed class DependencyProperty : ISerializable
    //{
    //    private PropertyMetadata defaultMetadata;
    //    private static IDictionary<int, DependencyProperty> dependencyProperties = new Dictionary<int, DependencyProperty>();
    //    [NonSerialized]
    //    private bool isEvent;
    //    private bool isRegistered;
    //    private byte knownIndex;
    //    private static KnownDependencyProperty[] knownProperties = new KnownDependencyProperty[0x100];
    //    private string name = string.Empty;
    //    private Type ownerType;
    //    private Type propertyType;
    //    private Type validatorType;

    //    private DependencyProperty(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, Type validatorType, bool isRegistered)
    //    {
    //        this.name = name;
    //        this.propertyType = propertyType;
    //        this.ownerType = ownerType;
    //        this.validatorType = validatorType;
    //        this.isRegistered = isRegistered;
    //        this.defaultMetadata = defaultMetadata;
    //        this.defaultMetadata.Seal(this, propertyType);
    //        this.isEvent = typeof(Delegate).IsAssignableFrom(this.propertyType) && ((this.defaultMetadata == null) || (((byte) (this.defaultMetadata.Options & DependencyPropertyOptions.DelegateProperty)) == 0));
    //    }

    //    internal static DependencyProperty FromKnown(byte byteVal)
    //    {
    //        if (knownProperties[byteVal] == null)
    //        {
    //            throw new InvalidOperationException(SR.GetString("Error_NotRegisteredAs", new object[] { knownProperties[byteVal].dependencyProperty.ToString() }));
    //        }
    //        return knownProperties[byteVal].dependencyProperty;
    //    }

    //    public static DependencyProperty FromName(string propertyName, Type ownerType)
    //    {
    //        if (propertyName == null)
    //        {
    //            throw new ArgumentNullException("propertyName");
    //        }
    //        if (ownerType == null)
    //        {
    //            throw new ArgumentNullException("ownerType");
    //        }
    //        DependencyProperty property = null;
    //        while ((property == null) && (ownerType != null))
    //        {
    //            RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle);
    //            int key = propertyName.GetHashCode() ^ ownerType.GetHashCode();
    //            lock (((ICollection) dependencyProperties).SyncRoot)
    //            {
    //                if (dependencyProperties.ContainsKey(key))
    //                {
    //                    property = dependencyProperties[key];
    //                }
    //            }
    //            ownerType = ownerType.BaseType;
    //        }
    //        return property;
    //    }

    //    public static IList<DependencyProperty> FromType(Type ownerType)
    //    {
    //        if (ownerType == null)
    //        {
    //            throw new ArgumentNullException("ownerType");
    //        }
    //        RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle);
    //        List<DependencyProperty> list = new List<DependencyProperty>();
    //        lock (((ICollection) dependencyProperties).SyncRoot)
    //        {
    //            foreach (DependencyProperty property in dependencyProperties.Values)
    //            {
    //                //if (TypeProvider.IsSubclassOf(ownerType, property.ownerType) || (ownerType == property.ownerType))
    //                //{
    //                //    list.Add(property);
    //                //}
    //            }
    //        }
    //        return list.AsReadOnly();
    //    }

    //    private static object GetDefaultValue(string name, Type propertyType, Type ownerType)
    //    {
    //        if (name == null)
    //        {
    //            throw new ArgumentNullException("name");
    //        }
    //        if (name.Length == 0)
    //        {
    //            throw new ArgumentException(SR.GetString("Error_EmptyArgument"), "name");
    //        }
    //        if (propertyType == null)
    //        {
    //            throw new ArgumentNullException("propertyType");
    //        }
    //        if (ownerType == null)
    //        {
    //            throw new ArgumentNullException("ownerType");
    //        }
    //        object obj2 = null;
    //        if (propertyType.IsValueType)
    //        {
    //            try
    //            {
    //                if (propertyType.IsEnum)
    //                {
    //                    Array values = Enum.GetValues(propertyType);
    //                    if (values.Length > 0)
    //                    {
    //                        return values.GetValue(0);
    //                    }
    //                    return Activator.CreateInstance(propertyType);
    //                }
    //                obj2 = Activator.CreateInstance(propertyType);
    //            }
    //            catch
    //            {
    //            }
    //        }
    //        return obj2;
    //    }

    //    public override int GetHashCode()
    //    {
    //        return (this.name.GetHashCode() ^ this.ownerType.GetHashCode());
    //    }

    //    public static DependencyProperty Register(string name, Type propertyType, Type ownerType)
    //    {
    //        return ValidateAndRegister(name, propertyType, ownerType, null, null, true);
    //    }

    //    public static DependencyProperty Register(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata)
    //    {
    //        return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, null, true);
    //    }

    //    internal static void RegisterAsKnown(DependencyProperty dependencyProperty, byte byteVal, PropertyValidity propertyValidity)
    //    {
    //        if (dependencyProperty == null)
    //        {
    //            throw new ArgumentNullException("dependencyProperty");
    //        }
    //        if (knownProperties[byteVal] != null)
    //        {
    //            //throw new InvalidOperationException(Sprivate static DependencyProperty ValidateAndRegisterR.GetString("Error_AlreadyRegisteredAs", new object[] { knownProperties[byteVal].dependencyProperty.ToString() }));
    //        }
    //        dependencyProperty.KnownIndex = byteVal;
    //        knownProperties[byteVal] = new KnownDependencyProperty(dependencyProperty, propertyValidity);
    //    }

    //    public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType)
    //    {
    //        return ValidateAndRegister(name, propertyType, ownerType, null, null, false);
    //    }

    //    public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata)
    //    {
    //        return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, null, false);
    //    }

    //    public static DependencyProperty RegisterAttached(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, Type validatorType)
    //    {
    //        if (validatorType == null)
    //        {
    //            throw new ArgumentNullException("validatorType");
    //        }
    //        //if (!typeof(Validator).IsAssignableFrom(validatorType))
    //        //{
    //        //    throw new ArgumentException(SR.GetString("Error_ValidatorTypeIsInvalid"), "validatorType");
    //        //}
    //        return ValidateAndRegister(name, propertyType, ownerType, defaultMetadata, validatorType, false);
    //    }

    //    [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
    //    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    //    {
    //        info.AddValue("type", this.ownerType);
    //        info.AddValue("name", this.name);
    //        info.SetType(typeof(DependencyPropertyReference));
    //    }

    //    public override string ToString()
    //    {
    //        return this.name;
    //    }

    //    private static DependencyProperty ValidateAndRegister(string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, Type validatorType, bool isRegistered)
    //    {
    //        if (name == null)
    //        {
    //            throw new ArgumentNullException("name");
    //        }
    //        if (name.Length == 0)
    //        {
    //            throw new ArgumentException(SR.GetString("Error_EmptyArgument"), "name");
    //        }
    //        if (propertyType == null)
    //        {
    //            throw new ArgumentNullException("propertyType");
    //        }
    //        if (ownerType == null)
    //        {
    //            throw new ArgumentNullException("ownerType");
    //        }
    //        FieldInfo field = null;
    //        bool flag = typeof(Delegate).IsAssignableFrom(propertyType) && ((defaultMetadata == null) || (((byte) (defaultMetadata.Options & DependencyPropertyOptions.DelegateProperty)) == 0));
    //        if ((flag && (defaultMetadata != null)) && defaultMetadata.IsMetaProperty)
    //        {
    //            throw new ArgumentException(SR.GetString("Error_DPAddHandlerMetaProperty"), "defaultMetadata");
    //        }
    //        if (flag)
    //        {
    //            field = ownerType.GetField(name + "Event", BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
    //        }
    //        else
    //        {
    //            field = ownerType.GetField(name + "Property", BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
    //        }
    //        if (field == null)
    //        {
    //            throw new ArgumentException(SR.GetString(flag ? "Error_DynamicEventNotSupported" : "Error_DynamicPropertyNotSupported", new object[] { ownerType.FullName, name }), "ownerType");
    //        }
    //        PropertyMetadata metadata = null;
    //        if (defaultMetadata == null)
    //        {
    //            metadata = new PropertyMetadata(GetDefaultValue(name, propertyType, ownerType));
    //        }
    //        else
    //        {
    //            metadata = defaultMetadata;
    //            if (metadata.DefaultValue == null)
    //            {
    //                metadata.DefaultValue = GetDefaultValue(name, propertyType, ownerType);
    //            }
    //        }
    //        DependencyProperty property = new DependencyProperty(name, propertyType, ownerType, metadata, validatorType, isRegistered);
    //        lock (((ICollection) dependencyProperties).SyncRoot)
    //        {
    //            if (dependencyProperties.ContainsKey(property.GetHashCode()))
    //            {
    //                throw new InvalidOperationException(SR.GetString("Error_DPAlreadyExist", new object[] { name, ownerType.FullName }));
    //            }
    //            dependencyProperties.Add(property.GetHashCode(), property);
    //        }
    //        return property;
    //    }

    //    public PropertyMetadata DefaultMetadata
    //    {
    //        get
    //        {
    //            return this.defaultMetadata;
    //        }
    //    }

    //    public bool IsAttached
    //    {
    //        get
    //        {
    //            return !this.isRegistered;
    //        }
    //    }

    //    public bool IsEvent
    //    {
    //        get
    //        {
    //            return this.isEvent;
    //        }
    //    }

    //    internal bool IsKnown
    //    {
    //        get
    //        {
    //            return (this.knownIndex != 0);
    //        }
    //    }

    //    internal byte KnownIndex
    //    {
    //        get
    //        {
    //            return this.knownIndex;
    //        }
    //        set
    //        {
    //            this.knownIndex = value;
    //        }
    //    }

    //    public string Name
    //    {
    //        get
    //        {
    //            return this.name;
    //        }
    //    }

    //    public Type OwnerType
    //    {
    //        get
    //        {
    //            return this.ownerType;
    //        }
    //    }

    //    public Type PropertyType
    //    {
    //        get
    //        {
    //            return this.propertyType;
    //        }
    //    }

    //    public Type ValidatorType
    //    {
    //        get
    //        {
    //            return this.validatorType;
    //        }
    //    }

    //    internal PropertyValidity Validity
    //    {
    //        get
    //        {
    //            if (!this.IsKnown)
    //            {
    //                return PropertyValidity.Always;
    //            }
    //            return knownProperties[this.knownIndex].propertyValidity;
    //        }
    //    }

    //    [Serializable]
    //    private sealed class DependencyPropertyReference : IObjectReference
    //    {
    //        private string name;
    //        private Type type;

    //        public object GetRealObject(StreamingContext context)
    //        {
    //            return DependencyProperty.FromName(this.name, this.type);
    //        }
    //    }

    //    private class KnownDependencyProperty
    //    {
    //        internal DependencyProperty dependencyProperty;
    //        internal DependencyProperty.PropertyValidity propertyValidity;

    //        internal KnownDependencyProperty(DependencyProperty dependencyProperty, DependencyProperty.PropertyValidity propertyValidity)
    //        {
    //            this.dependencyProperty = dependencyProperty;
    //            this.propertyValidity = propertyValidity;
    //        }
    //    }

    //    internal enum PropertyValidity
    //    {
    //        Uninitialize,
    //        Reexecute,
    //        Always
    //    }
    //}


////internal interface IDependencyObjectAccessor
////    {
////        T[] GetInvocationList<T>(DependencyProperty dependencyEvent);
////        void InitializeActivatingInstanceForRuntime(DependencyObject parentDependencyObject, IWorkflowCoreRuntime workflowCoreRuntime);
////        void InitializeDefinitionForRuntime(DependencyObject parentDependencyObject);
         
////    }

////   public abstract class DependencyObject : IComponent, IDependencyObjectAccessor, IDisposable
////    {
////        private IDictionary<DependencyProperty, object> dependencyPropertyValues;
////        [NonSerialized]
////        private IDictionary<DependencyProperty, object> metaProperties = new Dictionary<DependencyProperty, object>();
////        private static DependencyProperty ParentDependencyObjectProperty = DependencyProperty.Register("ParentDependencyObject", typeof(DependencyObject), typeof(DependencyObject), new PropertyMetadata(null, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));
////        private static DependencyProperty ReadonlyProperty = DependencyProperty.Register("Readonly", typeof(bool), typeof(DependencyObject), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));
////        [NonSerialized]
////        private bool readonlyPropertyValue;
////        private static DependencyProperty SiteProperty = DependencyProperty.Register("Site", typeof(ISite), typeof(DependencyObject), new PropertyMetadata(DependencyPropertyOptions.Metadata, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));
////        private static DependencyProperty UserDataProperty = DependencyProperty.Register("UserData", typeof(IDictionary), typeof(DependencyObject), new PropertyMetadata(DependencyPropertyOptions.Metadata | DependencyPropertyOptions.ReadOnly, new Attribute[] { new BrowsableAttribute(false), new DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden) }));

////        private event EventHandler disposed;

////        //event EventHandler IComponent.Disposed;

////        protected DependencyObject()
////        {
////            this.SetReadOnlyPropertyValue(ReadonlyProperty, false);
////            this.readonlyPropertyValue = false;
////            this.SetReadOnlyPropertyValue(UserDataProperty, Hashtable.Synchronized(new Hashtable()));
////        }

////        public void AddHandler(DependencyProperty dependencyEvent, object value)
////        {
////            if (dependencyEvent == null)
////            {
////                throw new ArgumentNullException("dependencyEvent");
////            }
////            if (value == null)
////            {
////                throw new ArgumentNullException("value");
////            }
////            if (value is ActivityBind)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPSetValueBind"), "value");
////            }
////            if ((dependencyEvent.DefaultMetadata != null) && dependencyEvent.DefaultMetadata.IsMetaProperty)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPAddHandlerMetaProperty"), "dependencyEvent");
////            }
////            if (!dependencyEvent.IsEvent)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPAddHandlerNonEvent"), "dependencyEvent");
////            }
////            if (dependencyEvent.PropertyType == null)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPPropertyTypeMissing"), "dependencyEvent");
////            }
////            if (dependencyEvent.OwnerType == null)
////            {
////                throw new ArgumentException(SR.GetString("Error_MissingOwnerTypeProperty"), "dependencyEvent");
////            }
////            if (!dependencyEvent.IsAttached && !dependencyEvent.OwnerType.IsAssignableFrom(base.GetType()))
////            {
////                throw new InvalidOperationException(SR.GetString("Error_InvalidDependencyProperty", new object[] { base.GetType().FullName, dependencyEvent.Name, dependencyEvent.OwnerType.FullName }));
////            }
////            if ((value != null) && !dependencyEvent.PropertyType.IsAssignableFrom(value.GetType()))
////            {
////                throw new ArgumentException(SR.GetString("Error_DynamicPropertyTypeValueMismatch", new object[] { dependencyEvent.PropertyType.FullName, dependencyEvent.Name, value.GetType().FullName }), "value");
////            }
////            IDictionary<DependencyProperty, object> dependencyPropertyValues = this.DependencyPropertyValues;
////            ArrayList list = null;
////            if (dependencyPropertyValues.ContainsKey(dependencyEvent))
////            {
////                list = (ArrayList) dependencyPropertyValues[dependencyEvent];
////            }
////            else
////            {
////                list = new ArrayList();
////                dependencyPropertyValues.Add(dependencyEvent, list);
////            }
////            list.Add(value);
////            if (this.DesignMode && this.metaProperties.ContainsKey(dependencyEvent))
////            {
////                this.metaProperties.Remove(dependencyEvent);
////            }
////        }

////        public void Dispose()
////        {
////            this.Dispose(true);
////            GC.SuppressFinalize(this);
////        }

////        protected virtual void Dispose(bool disposing)
////        {
////            if (disposing)
////            {
////                if ((this.Site != null) && (this.Site.Container != null))
////                {
////                    this.Site.Container.Remove(this);
////                }
////                if (this.disposed != null)
////                {
////                    this.disposed(this, EventArgs.Empty);
////                }
////            }
////        }

////        ~DependencyObject()
////        {
////            this.Dispose(false);
////        }

////        internal virtual void FixUpMetaProperties(DependencyObject originalObject)
////        {
////            if (originalObject == null)
////            {
////                throw new ArgumentNullException();
////            }
////            this.metaProperties = originalObject.metaProperties;
////            this.readonlyPropertyValue = true;
////            foreach (KeyValuePair<DependencyProperty, object> pair in this.DependencyPropertyValues)
////            {
////                if ((pair.Key != ParentDependencyObjectProperty) && originalObject.DependencyPropertyValues.ContainsKey(pair.Key))
////                {
////                    object obj2 = originalObject.DependencyPropertyValues[pair.Key];
////                    if (pair.Value is DependencyObject)
////                    {
////                        ((DependencyObject) pair.Value).FixUpMetaProperties(obj2 as DependencyObject);
////                    }
////                    else if (pair.Value is WorkflowParameterBindingCollection)
////                    {
////                        IList list = pair.Value as IList;
////                        IList list2 = obj2 as IList;
////                        for (int i = 0; i < list.Count; i++)
////                        {
////                            ((DependencyObject) list[i]).FixUpMetaProperties(list2[i] as DependencyObject);
////                        }
////                    }
////                }
////            }
////        }

////        public ActivityBind GetBinding(DependencyProperty dependencyProperty)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            if (!this.metaProperties.ContainsKey(dependencyProperty))
////            {
////                return null;
////            }
////            return (this.metaProperties[dependencyProperty] as ActivityBind);
////        }

////        [EditorBrowsable(EditorBrowsableState.Never)]
////        protected virtual object GetBoundValue(ActivityBind bind, Type targetType)
////        {
////            if (bind == null)
////            {
////                throw new ArgumentNullException("bind");
////            }
////            if (targetType == null)
////            {
////                throw new ArgumentNullException("targetType");
////            }
////            object runtimeValue = bind;
////            Activity activity = this.ResolveOwnerActivity();
////            if (activity != null)
////            {
////                runtimeValue = bind.GetRuntimeValue(activity, targetType);
////            }
////            return runtimeValue;
////        }

////        internal object GetHandler(DependencyProperty dependencyEvent)
////        {
////            if (dependencyEvent == null)
////            {
////                throw new ArgumentNullException("dependencyEvent");
////            }
////            if (!dependencyEvent.IsEvent)
////            {
////                throw new ArgumentException("dependencyEvent");
////            }
////            IDictionary<DependencyProperty, object> dependencyPropertyValues = this.DependencyPropertyValues;
////            if (dependencyPropertyValues.ContainsKey(dependencyEvent))
////            {
////                ArrayList list = dependencyPropertyValues[dependencyEvent] as ArrayList;
////                if ((list != null) && (list.Count != 0))
////                {
////                    if (list.Count == 1)
////                    {
////                        return list[0];
////                    }
////                    Delegate a = list[0] as Delegate;
////                    for (int i = 1; i < list.Count; i++)
////                    {
////                        a = Delegate.Combine(a, list[i] as Delegate);
////                    }
////                    return a;
////                }
////            }
////            return null;
////        }

////        protected T[] GetInvocationList<T>(DependencyProperty dependencyEvent)
////        {
////            if (dependencyEvent == null)
////            {
////                throw new ArgumentNullException("dependencyEvent");
////            }
////            if (!dependencyEvent.IsEvent)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPAddHandlerNonEvent"), "dependencyEvent");
////            }
////            IDictionary<DependencyProperty, object> dependencyPropertyValues = null;
////            if (this.DependencyPropertyValues.ContainsKey(dependencyEvent))
////            {
////                dependencyPropertyValues = this.DependencyPropertyValues;
////            }
////            else
////            {
////                dependencyPropertyValues = this.metaProperties;
////            }
////            List<T> list = new List<T>();
////            if (dependencyPropertyValues.ContainsKey(dependencyEvent))
////            {
////                if (dependencyPropertyValues[dependencyEvent] is ActivityBind)
////                {
////                    if (!this.DesignMode)
////                    {
////                        T item = default(T);
////                        item = (T) this.GetBoundValue((ActivityBind) dependencyPropertyValues[dependencyEvent], typeof(T));
////                        if (item != null)
////                        {
////                            list.Add(item);
////                        }
////                    }
////                }
////                else
////                {
////                    foreach (object obj2 in (ArrayList) dependencyPropertyValues[dependencyEvent])
////                    {
////                        if (obj2 is T)
////                        {
////                            list.Add((T) obj2);
////                        }
////                    }
////                }
////            }
////            return list.ToArray();
////        }

////        public object GetValue(DependencyProperty dependencyProperty)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            if (dependencyProperty.IsEvent)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPGetValueHandler"), "dependencyProperty");
////            }
////            PropertyMetadata defaultMetadata = dependencyProperty.DefaultMetadata;
////            if (defaultMetadata.GetValueOverride != null)
////            {
////                return defaultMetadata.GetValueOverride(this);
////            }
////            return this.GetValueCommon(dependencyProperty, defaultMetadata);
////        }

////        [EditorBrowsable(EditorBrowsableState.Never)]
////        public object GetValueBase(DependencyProperty dependencyProperty)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            return this.GetValueCommon(dependencyProperty, dependencyProperty.DefaultMetadata);
////        }

////        private object GetValueCommon(DependencyProperty dependencyProperty, PropertyMetadata metadata)
////        {
////            object boundValue;
////            if (!this.DependencyPropertyValues.TryGetValue(dependencyProperty, out boundValue) && ((this.metaProperties == null) || !this.metaProperties.TryGetValue(dependencyProperty, out boundValue)))
////            {
////                return dependencyProperty.DefaultMetadata.DefaultValue;
////            }
////            if (((this.metaProperties != null) && !this.DesignMode) && ((boundValue is ActivityBind) && !typeof(ActivityBind).IsAssignableFrom(dependencyProperty.PropertyType)))
////            {
////                boundValue = this.GetBoundValue((ActivityBind) boundValue, dependencyProperty.PropertyType);
////            }
////            if ((boundValue == null) || (boundValue is ActivityBind))
////            {
////                return dependencyProperty.DefaultMetadata.DefaultValue;
////            }
////            if (!dependencyProperty.PropertyType.IsAssignableFrom(boundValue.GetType()))
////            {
////                throw new InvalidOperationException(SR.GetString("Error_DynamicPropertyTypeValueMismatch", new object[] { dependencyProperty.PropertyType.FullName, dependencyProperty.Name, boundValue.GetType().FullName }));
////            }
////            return boundValue;
////        }

////        protected virtual void InitializeProperties()
////        {
////        }

////        public bool IsBindingSet(DependencyProperty dependencyProperty)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            return ((!this.DependencyPropertyValues.ContainsKey(dependencyProperty) && this.metaProperties.ContainsKey(dependencyProperty)) && (this.metaProperties[dependencyProperty] is ActivityBind));
////        }

////        public bool MetaEquals(DependencyObject dependencyObject)
////        {
////            return ((dependencyObject != null) && (dependencyObject.metaProperties == this.metaProperties));
////        }

////        internal virtual void OnInitializeActivatingInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
////        {
////            this.InitializeProperties();
////        }

////        internal virtual void OnInitializeDefinitionForRuntime()
////        {
////        }

////        internal virtual void OnInitializeInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
////        {
////        }

////        public void RemoveHandler(DependencyProperty dependencyEvent, object value)
////        {
////            if (dependencyEvent == null)
////            {
////                throw new ArgumentNullException("dependencyEvent");
////            }
////            if (value == null)
////            {
////                throw new ArgumentNullException("value");
////            }
////            if (value is ActivityBind)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPRemoveHandlerBind"), "value");
////            }
////            if ((dependencyEvent.DefaultMetadata != null) && dependencyEvent.DefaultMetadata.IsMetaProperty)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPAddHandlerMetaProperty"), "dependencyEvent");
////            }
////            if (!dependencyEvent.IsEvent)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPAddHandlerNonEvent"), "dependencyEvent");
////            }
////            IDictionary<DependencyProperty, object> dependencyPropertyValues = this.DependencyPropertyValues;
////            if (dependencyPropertyValues.ContainsKey(dependencyEvent))
////            {
////                ArrayList list = (ArrayList) dependencyPropertyValues[dependencyEvent];
////                if (list.Contains(value))
////                {
////                    list.Remove(value);
////                }
////                if (list.Count == 0)
////                {
////                    dependencyPropertyValues.Remove(dependencyEvent);
////                }
////            }
////        }

////        public bool RemoveProperty(DependencyProperty dependencyProperty)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            if ((dependencyProperty.DefaultMetadata != null) && dependencyProperty.DefaultMetadata.IsMetaProperty)
////            {
////                if (!this.DesignMode)
////                {
////                    throw new InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"));
////                }
////                return this.metaProperties.Remove(dependencyProperty);
////            }
////            return (this.metaProperties.Remove(dependencyProperty) | this.DependencyPropertyValues.Remove(dependencyProperty));
////        }

////        private ProgramStatement ResolveOwnerActivity()
////        {
////            DependencyObject parentDependencyObject = this;
////            while ((parentDependencyObject != null) && !(parentDependencyObject is Activity))
////            {
////                parentDependencyObject = parentDependencyObject.ParentDependencyObject;
////            }
////            return (parentDependencyObject as Activity);
////        }

////        public void SetBinding(DependencyProperty dependencyProperty, ActivityBind bind)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            if ((dependencyProperty.DefaultMetadata != null) && dependencyProperty.DefaultMetadata.IsReadOnly)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPReadOnly"), "dependencyProperty");
////            }
////            if (dependencyProperty.OwnerType == null)
////            {
////                throw new ArgumentException(SR.GetString("Error_MissingOwnerTypeProperty"), "dependencyProperty");
////            }
////            if (!dependencyProperty.IsAttached && !dependencyProperty.OwnerType.IsAssignableFrom(base.GetType()))
////            {
////                throw new InvalidOperationException(SR.GetString("Error_InvalidDependencyProperty", new object[] { base.GetType().FullName, dependencyProperty.Name, dependencyProperty.OwnerType.FullName }));
////            }
////            if (!this.DesignMode)
////            {
////                throw new InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"));
////            }
////            if (((dependencyProperty.DefaultMetadata != null) && dependencyProperty.DefaultMetadata.IsMetaProperty) && !typeof(ActivityBind).IsAssignableFrom(dependencyProperty.PropertyType))
////            {
////                throw new ArgumentException(SR.GetString("Error_DPMetaPropertyBinding"), "dependencyProperty");
////            }
////            if (this.metaProperties.ContainsKey(dependencyProperty))
////            {
////                this.metaProperties[dependencyProperty] = bind;
////            }
////            else
////            {
////                this.metaProperties.Add(dependencyProperty, bind);
////            }
////            if (this.DependencyPropertyValues.ContainsKey(dependencyProperty))
////            {
////                this.DependencyPropertyValues.Remove(dependencyProperty);
////            }
////        }

////        [EditorBrowsable(EditorBrowsableState.Never)]
////        protected virtual void SetBoundValue(ActivityBind bind, object value)
////        {
////            if (bind == null)
////            {
////                throw new ArgumentNullException("bind");
////            }
////            Activity activity = this.ResolveOwnerActivity();
////            if (activity != null)
////            {
////                bind.SetRuntimeValue(activity, value);
////            }
////        }

////        protected internal void SetReadOnlyPropertyValue(DependencyProperty dependencyProperty, object value)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            if (!dependencyProperty.DefaultMetadata.IsReadOnly)
////            {
////                throw new InvalidOperationException(SR.GetString("Error_NotReadOnlyProperty", new object[] { dependencyProperty.Name, dependencyProperty.OwnerType.FullName }));
////            }
////            if (!dependencyProperty.IsAttached && !dependencyProperty.OwnerType.IsAssignableFrom(base.GetType()))
////            {
////                throw new InvalidOperationException(SR.GetString("Error_InvalidDependencyProperty", new object[] { base.GetType().FullName, dependencyProperty.Name, dependencyProperty.OwnerType.FullName }));
////            }
////            IDictionary<DependencyProperty, object> metaProperties = null;
////            if (dependencyProperty.DefaultMetadata.IsMetaProperty)
////            {
////                metaProperties = this.metaProperties;
////            }
////            else
////            {
////                metaProperties = this.DependencyPropertyValues;
////            }
////            if (metaProperties.ContainsKey(dependencyProperty))
////            {
////                metaProperties[dependencyProperty] = value;
////            }
////            else
////            {
////                metaProperties.Add(dependencyProperty, value);
////            }
////        }

////        public void SetValue(DependencyProperty dependencyProperty, object value)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            PropertyMetadata defaultMetadata = dependencyProperty.DefaultMetadata;
////            this.SetValueCommon(dependencyProperty, value, defaultMetadata, true);
////        }

////        [EditorBrowsable(EditorBrowsableState.Never)]
////        public void SetValueBase(DependencyProperty dependencyProperty, object value)
////        {
////            if (dependencyProperty == null)
////            {
////                throw new ArgumentNullException("dependencyProperty");
////            }
////            PropertyMetadata defaultMetadata = dependencyProperty.DefaultMetadata;
////            this.SetValueCommon(dependencyProperty, value, defaultMetadata, defaultMetadata.ShouldAlwaysCallOverride);
////        }

////        internal void SetValueCommon(DependencyProperty dependencyProperty, object value, PropertyMetadata metadata, bool shouldCallSetValueOverrideIfExists)
////        {
////            if (dependencyProperty.DefaultMetadata.IsReadOnly)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPReadOnly"), "dependencyProperty");
////            }
////            if (value is ActivityBind)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPSetValueBind"), "value");
////            }
////            if (dependencyProperty.IsEvent)
////            {
////                throw new ArgumentException(SR.GetString("Error_DPSetValueHandler"), "dependencyProperty");
////            }
////            if (!dependencyProperty.IsAttached && !dependencyProperty.OwnerType.IsAssignableFrom(base.GetType()))
////            {
////                throw new InvalidOperationException(SR.GetString("Error_InvalidDependencyProperty", new object[] { base.GetType().FullName, dependencyProperty.Name, dependencyProperty.OwnerType.FullName }));
////            }
////            if ((!this.DesignMode && dependencyProperty.DefaultMetadata.IsMetaProperty) && (dependencyProperty != ConditionTypeConverter.DeclarativeConditionDynamicProp))
////            {
////                throw new InvalidOperationException(SR.GetString("Error_CanNotChangeAtRuntime"));
////            }
////            if ((value != null) && !dependencyProperty.PropertyType.IsAssignableFrom(value.GetType()))
////            {
////                throw new ArgumentException(SR.GetString("Error_DynamicPropertyTypeValueMismatch", new object[] { dependencyProperty.PropertyType.FullName, dependencyProperty.Name, value.GetType().FullName }), "value");
////            }
////            if (shouldCallSetValueOverrideIfExists && (metadata.SetValueOverride != null))
////            {
////                metadata.SetValueOverride(this, value);
////            }
////            else
////            {
////                IDictionary<DependencyProperty, object> metaProperties = null;
////                if (dependencyProperty.DefaultMetadata.IsMetaProperty)
////                {
////                    metaProperties = this.metaProperties;
////                }
////                else
////                {
////                    metaProperties = this.DependencyPropertyValues;
////                }
////                object obj2 = null;
////                if ((this.metaProperties != null) && this.metaProperties.ContainsKey(dependencyProperty))
////                {
////                    obj2 = this.metaProperties[dependencyProperty];
////                    if (this.DesignMode)
////                    {
////                        this.metaProperties.Remove(dependencyProperty);
////                    }
////                }
////                if (!this.DesignMode && (obj2 is ActivityBind))
////                {
////                    this.SetBoundValue((ActivityBind) obj2, value);
////                }
////                else if (metaProperties.ContainsKey(dependencyProperty))
////                {
////                    metaProperties[dependencyProperty] = value;
////                }
////                else
////                {
////                    metaProperties.Add(dependencyProperty, value);
////                }
////            }
////        }

////        T[] IDependencyObjectAccessor.GetInvocationList<T>(DependencyProperty dependencyEvent)
////        {
////            return this.GetInvocationList<T>(dependencyEvent);
////        }

////        void IDependencyObjectAccessor.InitializeActivatingInstanceForRuntime(DependencyObject parentDependencyObject, IWorkflowCoreRuntime workflowCoreRuntime)
////        {
////            if (parentDependencyObject != null)
////            {
////                this.DependencyPropertyValues[ParentDependencyObjectProperty] = parentDependencyObject;
////            }
////            foreach (DependencyProperty property in this.MetaDependencyProperties)
////            {
////                object obj2 = this.metaProperties[property];
////                if (obj2 is DependencyObject)
////                {
////                    ((IDependencyObjectAccessor) obj2).InitializeActivatingInstanceForRuntime(this, workflowCoreRuntime);
////                    this.DependencyPropertyValues[property] = obj2;
////                }
////                else if (obj2 is WorkflowParameterBindingCollection)
////                {
////                    IList list = obj2 as IList;
////                    for (int i = 0; i < list.Count; i++)
////                    {
////                        ((IDependencyObjectAccessor) list[i]).InitializeActivatingInstanceForRuntime(this, workflowCoreRuntime);
////                    }
////                    this.DependencyPropertyValues[property] = obj2;
////                }
////            }
////            this.OnInitializeActivatingInstanceForRuntime(workflowCoreRuntime);
////            this.Readonly = true;
////        }

////        void IDependencyObjectAccessor.InitializeDefinitionForRuntime(DependencyObject parentDependencyObject)
////        {
////            if (parentDependencyObject != null)
////            {
////                this.DependencyPropertyValues[ParentDependencyObjectProperty] = parentDependencyObject;
////            }
////            foreach (DependencyProperty property in this.MetaDependencyProperties)
////            {
////                object obj2 = this.metaProperties[property];
////                if (obj2 is DependencyObject)
////                {
////                    ((IDependencyObjectAccessor) obj2).InitializeDefinitionForRuntime(this);
////                    this.DependencyPropertyValues[property] = obj2;
////                    continue;
////                }
////                if (obj2 is WorkflowParameterBindingCollection)
////                {
////                    IList list = obj2 as IList;
////                    for (int i = 0; i < list.Count; i++)
////                    {
////                        ((IDependencyObjectAccessor) list[i]).InitializeDefinitionForRuntime(this);
////                    }
////                    this.DependencyPropertyValues[property] = obj2;
////                    continue;
////                }
////                if (obj2 is ActivityBind)
////                {
////                    Activity activity = this.ResolveOwnerActivity();
////                    if (activity == null)
////                    {
////                        continue;
////                    }
////                    ((ActivityBind) obj2).SetContext(activity);
////                }
////            }
////            this.OnInitializeDefinitionForRuntime();
////            this.InitializeProperties();
////            this.Readonly = true;
////        }

////        void IDependencyObjectAccessor.InitializeInstanceForRuntime(IWorkflowCoreRuntime workflowCoreRuntime)
////        {
////            this.OnInitializeInstanceForRuntime(workflowCoreRuntime);
////        }

////        internal IDictionary<DependencyProperty, object> DependencyPropertyValues
////        {
////            get
////            {
////                if (this.dependencyPropertyValues == null)
////                {
////                    this.dependencyPropertyValues = new Dictionary<DependencyProperty, object>();
////                }
////                return this.dependencyPropertyValues;
////            }
////        }

////        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
////        protected internal bool DesignMode
////        {
////            get
////            {
////                return !this.readonlyPropertyValue;
////            }
////        }

////        internal IList<DependencyProperty> MetaDependencyProperties
////        {
////            get
////            {
////                return new List<DependencyProperty>(this.metaProperties.Keys).AsReadOnly();
////            }
////        }

////        protected DependencyObject ParentDependencyObject
////        {
////            get
////            {
////                return (DependencyObject) this.GetValue(ParentDependencyObjectProperty);
////            }
////        }

////        internal bool Readonly
////        {
////            get
////            {
////                return (bool) this.GetValue(ReadonlyProperty);
////            }
////            set
////            {
////                this.SetReadOnlyPropertyValue(ReadonlyProperty, value);
////                this.readonlyPropertyValue = value;
////            }
////        }

////        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), EditorBrowsable(EditorBrowsableState.Never), Browsable(false)]
////        public ISite Site
////        {
////            get
////            {
////                return (ISite) this.GetValue(SiteProperty);
////            }
////            set
////            {
////                this.SetValue(SiteProperty, value);
////            }
////        }

////        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]
////        public IDictionary UserData
////        {
////            get
////            {
////                return (IDictionary) this.GetValue(UserDataProperty);
////            }
////        }
////    }
